/**	\file
 *	\brief Doubly linked nodes/lists.
 */

#ifndef MDS_LIST_INCLUDED
#define MDS_LIST_INCLUDED 1

#include "../types.h"

/** \brief Binary layout of a node.
 *
 *	Any other struct that shall be handled
 *	by a mds_list MUST match this binary layout.
 */
typedef struct mds_node_
{
	struct mds_node_ *next; 
	struct mds_node_ *prev; 
} mds_node;

/** \brief Simple doubly linked list.
 *
 */
typedef struct
{
	mds_node *head; /*!< first node   */
	mds_node *tail; /*!< last  node   */
	size_t    size; /*!< current size */
} mds_list;

#define MDS_LIST_INIT { NULL, NULL, 0 }

void    mds_list_push_back_(  mds_list *list, mds_node *node );
#define mds_list_push_back(list,node)  mds_list_push_back_(  (mds_list *)(list), (mds_node *)( node ) )

void mds_list_push_front_( mds_list *list, mds_node *node );
#define mds_list_push_front(list,node) mds_list_push_front_( (mds_list *)(list), (mds_node *)( node ) )

int     mds_list_owns_( const mds_list *list, const mds_node *node );
#define mds_list_owns(list,node) mds_list_owns_( (mds_list *)list, (const mds_node *)(node) )

mds_node *mds_list_pop_back_( mds_list *list );
#define   mds_list_pop_back(NODE,list) ( (NODE *) mds_list_pop_back_( (mds_list *)(list) ) )

mds_node *mds_list_pop_front_( mds_list *list );
#define   mds_list_pop_front(NODE,list) ( (NODE *) mds_list_pop_front_( (mds_list *)(list) ) )

mds_node *mds_list_unlink_( mds_list *list, mds_node *node );
#define   mds_list_unlink(NODE,list) ( (NODE *) mds_list_unlink_( (mds_list *)(list), (mds_node *)(node) ) )

#endif
